package cn.darkhorse.mesadmin.task;

import cn.darkhorse.alarm.mapper.MesAlarmMapper;
import cn.darkhorse.alarm.pojo.AlarmParameterSettings;
import cn.darkhorse.alarm.pojo.AlarmRecordInfo;
import cn.darkhorse.alarm.pojo.AlarmRecordUserInfo;
import cn.darkhorse.alarm.service.AlarmHandlerService;
import cn.darkhorse.alarm.service.AlarmParameterSettingsService;
import cn.darkhorse.alarm.service.AlarmRecordInfoService;
import cn.darkhorse.alarm.service.AlarmRecordUserInfoService;
import cn.darkhorse.alarm.service.alarm.AlarmManager;
import cn.darkhorse.alarm.service.alarm.BaseAlarm;
import cn.darkhorse.common.config.TaskConfig;
import cn.darkhorse.common.constant.CommonConstant;
import cn.darkhorse.common.util.RedisUtil;
import cn.darkhorse.device.pojo.IotPointTable;
import cn.darkhorse.device.pojo.MesDevice;
import cn.darkhorse.device.service.IotPointTableService;
import cn.darkhorse.device.service.MesDeviceService;
import cn.darkhorse.jpush.service.JPushService;
import cn.darkhorse.jpush.vo.JPushVO;
import cn.darkhorse.meswechat.dto.WxSendMessageMoreDTO;
import cn.darkhorse.meswechat.service.IWeChatService;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.mapper.SysUserMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* @Description: 处理缓存告警
* @Param:
* @return:
* @Author: Mr.Wang
* @Date:
*/
@Component("mesHandleAlarmTask")
public class MesHandleAlarmTask {
    @Resource
    private AlarmHandlerService handlerService;
    @Resource
    private AlarmParameterSettingsService parameterSettingsService;
    @Resource
    private SysUserMapper userMapper;
    @Resource
    private MesDeviceService mesDeviceService;
    @Resource
    private AlarmRecordInfoService alarmRecordInfoService;
    @Resource
    private IWeChatService weChatService;
    @Resource
    private AlarmRecordUserInfoService alarmRecordUserInfoService;
    @Resource
    private JPushService jPushService;

    /**
     * 处理实时报警任务
     */
//    @Scheduled(cron="0/15 * * * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void getAlarm() {
        //false不执行定时任务
        if(!TaskConfig.isFlag()){
            return;
        }
        List<String> alarmList = RedisUtil.getListAll(CommonConstant.ALARM_LIST);
        Collections.reverse(alarmList);
        if (alarmList.size()==0) {
            return;
        }
        // 获取报警参数设置
        Map<Long, AlarmParameterSettings> parameterSettingsMap=parameterSettingsService.getMap(null);
        // 获取全部设备
        Map<Long, MesDevice> deviceMap=mesDeviceService.list().stream().collect(Collectors.toMap(MesDevice::getId,Function.identity()));
        List<SysUser> sysUsers = userMapper.selectUserListNoAuth(new SysUser());
        Map<Long, SysUser> sysUserMap=sysUsers.stream().collect(Collectors.toMap(SysUser::getUserId, Function.identity()));
        // 查询每个设备最近一条报错信息(alarmDate)
        List<AlarmRecordInfo> recordInfoList=alarmRecordInfoService.getLastRecord();
        Map<String, String> paramsDescription = pointTableParamsDescription();
        //开关量Map
        Map<String,AlarmRecordInfo> recordSwitchMap=new HashMap<>();
        //限值值Map
        Map<String,AlarmRecordInfo> recordValueLimitMap=new HashMap<>();
        //连续值Map
        Map<String,AlarmRecordInfo> recordValueImmediateMap=new HashMap<>();
        for (AlarmRecordInfo recordInfo : recordInfoList) {
            String key=recordInfo.getDeviceId()+":"+recordInfo.getParameterId()+":"+recordInfo.getParameterType();
            if(BaseAlarm.ALARM_OTHER.equals(recordInfo.getAlarmType())){
                key = key+":"+recordInfo.getAlarmValue();
                recordSwitchMap.put(key,recordInfo);
            }
            //限值
            if(BaseAlarm.ALARM_LIMIT_VALUE.equals(recordInfo.getAlarmType())){
                 key=key+":"+recordInfo.getLimitType();
                recordValueLimitMap.put(key,recordInfo);
            }
            //连续
            if(BaseAlarm.ALARM_CONTINUOUS_VALUE.equals(recordInfo.getAlarmType())){
                 key=key+":"+recordInfo.getImmediatelyValue();
                recordValueImmediateMap.put(key,recordInfo);
            }
        }
        int size=alarmList.size();
        //每次最多一千条
        if(alarmList.size()>1000){
            size=1000;
        }
        //size=1000;
        for (int i=0;i<size;i++){
            handlerService.doHandler(alarmList.get(i),sysUserMap,parameterSettingsMap,deviceMap,
                    recordSwitchMap,recordValueLimitMap,recordValueImmediateMap,paramsDescription);
        }

    }

    /**
     * 发送微信模板消息
     */
    @Transactional(rollbackFor = Exception.class)
    public void sendWeChatMsg(){
        //false不执行定时任务
        if(!TaskConfig.isFlag()){
            return;
        }
        List<WxSendMessageMoreDTO> sendMsg = alarmRecordInfoService.getSendMsg();
        if(null!=sendMsg&&sendMsg.size()>0){
            for (WxSendMessageMoreDTO wxSendMessageMoreDTO : sendMsg) {
                String s="";
                if(StringUtils.isNotBlank(wxSendMessageMoreDTO.getOpenId())){
                     s= weChatService.sendMessage(wxSendMessageMoreDTO);
                }
                if("ok".equals(s)){
                    AlarmRecordUserInfo info =new AlarmRecordUserInfo();
                    LambdaQueryWrapper<AlarmRecordUserInfo> wrapper=new LambdaQueryWrapper<>();
                    wrapper.eq(AlarmRecordUserInfo::getUserId,wxSendMessageMoreDTO.getUserId());
                    wrapper.eq(AlarmRecordUserInfo::getRecordId,wxSendMessageMoreDTO.getRecordId());
                    info.setSendFlag(CommonConstant.YES);
                    alarmRecordUserInfoService.update(info,wrapper);
                }
            }
        }
    }
    /**
     * 发送微信模板消息
     */
    @Transactional(rollbackFor = Exception.class)
    public void sendJPushMsg(){
        //false不执行定时任务
        if(!TaskConfig.isFlag()){
            return;
        }
        List<JPushVO> sendMsg = jPushService.getJPushSendMsg();
        if(null!=sendMsg&&sendMsg.size()>0){
            for (JPushVO jPushVO : sendMsg) {
                String s="";
                String content="";
                String title="您有设备出现报警信息！";
                Map<String,String> extra=new HashMap<>();
                if(StringUtils.isNotBlank(jPushVO.getJpushRegistrationId())){
                    content="【"+jPushVO.getDeviceName()+"】"+"【"+jPushVO.getWarningParameters()+"】参数异常，请及时查看!";
                    extra.put("record_id",jPushVO.getRecordId().toString());
                    s= jPushService.sendMsg(jPushVO.getJpushRegistrationId(),content,title,extra);
                }
                if("ok".equals(s)){
                    AlarmRecordUserInfo info =new AlarmRecordUserInfo();
                    LambdaQueryWrapper<AlarmRecordUserInfo> wrapper=new LambdaQueryWrapper<>();
                    wrapper.eq(AlarmRecordUserInfo::getUserId,jPushVO.getUserId());
                    wrapper.eq(AlarmRecordUserInfo::getRecordId,jPushVO.getRecordId());
                    info.setSendFlag(CommonConstant.YES);
                    alarmRecordUserInfoService.update(info,wrapper);
                }
            }
        }
    }


    @Resource
    IotPointTableService iotPointTableService;

    /**
     * 点表设置参数说明
     */

    private Map<String,String> pointTableParamsDescription(){
        Map<String,String> paramsDescriptionMap = new HashMap<>();
        List<IotPointTable> pointTableList = iotPointTableService.list();
        pointTableList.forEach(item->{
            if(item.getDataType() == 0 || item.getDataType() == 3){
                String extraJson = item.getExtraJson();
                JSONArray parse = JSONArray.parse(extraJson);
                for(int i = 0;i<parse.size();i++){
                    JSONObject params = parse.getJSONObject(i);
                    paramsDescriptionMap.put(item.getId()+":"+params.getString("label"), params.getString("value"));
                }
            }
        });
        return paramsDescriptionMap;
    }









}
